package lib

import (
	"GameServer/Common/data"
	"GameServer/Common/utils"
	"GameServer/Game/errors"
	"GameServer/Game/m"
	"GameServer/Game/sp"
	"fmt"
	"math"

	log "github.com/sirupsen/logrus"
)

// 生成新的活动进度，不负责存储更新
func GetOrCreateActProgress(u *m.User, activId int64) (rP *m.SingleActivityProgress, err error) {
	//--Func--CheckRest---
	CheckProgressReset := func(u *m.User, orgProgress *m.SingleActivityProgress, actId int64, resetMonth int64, resetWeekDay int64) (newProgress *m.SingleActivityProgress) {
		switch actId {
		case data.ResidentActEnum.Login7: // 7 天循环登录
			actConfige, _ := GetLoginActConfigeTableInfo(actId)
			maxRound := int64(len(actConfige.Rewards))
			nowUnix := utils.TNow().Unix()
			// 签到时间和当天时间，不是同一天，需要更新
			if !utils.IsSameDay(nowUnix, u.LastSignInTime) {
				orgProgress.CurRound = (orgProgress.CurRound + 1) % math.MaxInt64
				if maxRound == orgProgress.TotalItemCount {
					orgProgress.TotalItemCount = 0
				}
			}
			// var needReset bool = false
			// nowTime := utils.TNow()
			// lastSignInTime := u.LastSignInTime   //上次签到时间
			// nowWeekDay := int(nowTime.Weekday()) //输出为 周日0 - 周六6
			// if nowWeekDay == 0 {
			// 	nowWeekDay = 7 // 周日变为7
			// }
			// orgProgress.CurRound = int64(nowWeekDay) //当前轮数设置为周数----无论是否重置
			// if int64(nowWeekDay) == resetWeekDay {   // resetWeekDay == 1
			// 	needReset = true // 周一需要重置
			// }
			// if orgProgress.CurRound == orgProgress.GainRoundReward {
			// 	needReset = false
			// }
			// // 两次签到事件相差7天，判断为一周或一周前的签到，需要重置
			// if (nowTime.Unix() - lastSignInTime) >= (86400 * 7) {
			// 	needReset = true
			// }
			// // 相差不满7天的情况下，当前星期数，小于上次签到的星期数，判断为上周签到，需要重置
			// if orgProgress.CurRound < orgProgress.GainRoundReward {
			// 	needReset = true
			// }
			// if needReset {
			// 	orgProgress.CurRoundItemCount = 0
			// 	orgProgress.GainRoundReward = 0
			// 	orgProgress.TotalItemCount = 0
			// }
			// if orgProgress.CurRound <= orgProgress.GainRoundReward {
			// 	orgProgress.Close = 1
			// } else {
			// 	orgProgress.Close = 0
			// }
			return orgProgress
		default:
			return orgProgress
		}
	}
	//---
	userProgressData := u.GetUserActProgress()
	// 读表
	tplActActivity, ok := data.Get("ActActivities", uint64(activId))
	if !ok {
		err = errors.NewErrcode(data.Errcode.ConfigNotFound, "没有找到激活活动配置,ActActivities")
		log.WithFields(log.Fields{
			"err":    err.Error(),
			"actvId": activId,
			"method": "GetOrCreateActProgress",
		}).Debug("没有找到激活活动配置,ActActivities")
		return nil, err
	}
	endT := tplActActivity.(data.ActActivity).EndTime
	resetMonth := tplActActivity.(data.ActActivity).ResetMonth     // 0-不设置 1-按月重置
	resetWeekDay := tplActActivity.(data.ActActivity).ResetWeekDay // 周几重置
	//fmt.Println(int(changT.Weekday())) //周日是星期0
	endTime, _ := utils.LayoutToTime(endT)
	nowTime := utils.TNow().Unix()
	if nowTime >= endTime.Unix() {
		err = errors.NewErrcode(data.Errcode.ServerErr, "不能创建一个过期的活动的进度")
		log.WithFields(log.Fields{
			"err":           err.Error(),
			"actId":         activId,
			"configEndTime": endT,
			"uid":           u.Uid.Hex(),
			"resetMonth":    resetMonth,
			"resetWeekDay":  resetWeekDay,
			"method":        "GetOrCreateActProgress",
		}).Debug("不能创建一个过期的活动的进度")
		return nil, err
	}
	actProgress, findProgress := userProgressData.GetActivityProgress(activId)
	//没有找到该活动的进度，可能未初始化
	if findProgress == false { //新建一个进度
		rP = &m.SingleActivityProgress{
			ActId:             activId,
			CurRound:          1,
			CurRoundItemCount: 0,
			TotalItemCount:    0,
			GainRoundReward:   0,
			EndTime:           endTime.Unix(),
		}
		rP = CheckProgressReset(u, rP, activId, int64(resetMonth), int64(resetWeekDay))
		userProgressData.ActivityProgressUpsetAndUpdate(rP)
		return rP, nil
	} else { //更新一个进度
		actProgress.ActId = activId
		actProgress.EndTime = endTime.Unix()
		actProgress = CheckProgressReset(u, actProgress, activId, int64(resetMonth), int64(resetWeekDay))
		userProgressData.ActivityProgressUpsetAndUpdate(actProgress)
		return actProgress, nil
	}
}

func TryActProgressLevelUp(from string, u *m.User, actId int64, addItemNum int64, PSend func(interface{}) error) (uProp *m.UpdateProp, progress *m.SingleActivityProgress, ActRewardList []*sp.ActivityReward, err error) {
	userProgressData := u.GetUserActProgress()
	actEnum := WhatIsActEnum(actId)
	switch actEnum {
	case data.ActivityEnum.Slot:
		uProp, progress, ActRewardList, err := actProgressLevelUp_Slot(from, u, actId, addItemNum, userProgressData, PSend)
		return uProp, progress, ActRewardList, err
	case data.ActivityEnum.Login:
		uProp, progress, ActRewardList, err := actProgressLevelUp_Login(from, u, actId, addItemNum, userProgressData, PSend)
		return uProp, progress, ActRewardList, err
	case data.ActivityEnum.Custom:
		uProp, progress, ActRewardList, err := actProgressLevelUp_Custom(from, u, actId, addItemNum, userProgressData, PSend)
		return uProp, progress, ActRewardList, err
	case data.ActivityEnum.BossCombat: // 世界BOSS进度不在这里修改
		uProp, progress, ActRewardList, err := actProgressLevelUp_BossCombat(u, actId, addItemNum, userProgressData)
		return uProp, progress, ActRewardList, err
	}
	return
}

func actProgressLevelUp_Slot(from string, u *m.User, actId int64, addItemNum int64, userProgressData *m.UserActivityProgress, PSend func(interface{}) error) (uProp *m.UpdateProp, progress *m.SingleActivityProgress, ActRewardList []*sp.ActivityReward, err error) {
	//return
	//(uProp *m.UpdateProp, progress *m.SingleActivityProgress, ActRewardList []*sp.ActivityReward, err error)
	actConfige, finderr := GetSlotActConfigeTableInfo(actId)
	if finderr != nil {
		// 该活动不是老虎机活动
		err = finderr
		return nil, nil, nil, err
	}
	progress, err = GetOrCreateActProgress(u, actId)
	if err != nil {
		// 证明该活动已经过期
		err = errors.NewErrcode(data.Errcode.ServerErr, "不能升级一个已过期的活动的进度")
		log.WithFields(log.Fields{
			"err":    err.Error(),
			"actId":  actId,
			"uid":    u.Uid.Hex(),
			"method": "actProgressLevelUp_Slot",
		}).Debug("不能升级一个已过期的活动的进度")
		return nil, nil, nil, err
	}
	var maxRound int64 = 0
	// 获取阶段奖励表
	slotRoundRewardList, finderr := GetSlotActRewardList(int64(actConfige.RewardId))
	if finderr == nil {
		maxRound = int64(len(slotRoundRewardList)) // 最大阶段
	}
	// 排行增加
	progress.RankId = AddItemToActRank(u, addItemNum, actId, int64(actConfige.RewardId), int64(progress.TotalItemCount))
	progress.CurRoundItemCount = (progress.CurRoundItemCount + addItemNum)
	progress.TotalItemCount = (progress.TotalItemCount + addItemNum)

	if progress.GainRoundReward >= int64(maxRound) || progress.CurRound > maxRound {
		// 已经获得最高阶段奖励：直接计数，不获得奖励
		// 当前轮数超过最高阶段奖励 ：直接计数，不获得奖励
		userProgressData.ActivityProgressUpsetAndUpdate(progress)
		return nil, progress, nil, nil
	}
	// ----------------------------------------------------
	FindRoundReward := func(roundId int64, list *[]data.SlotActivityReward) (curRoundReward data.SlotActivityReward, findR bool) {
		findR = false
		for _, roundR := range *list {
			if progress.CurRound == int64(roundR.Round) {
				curRoundReward = roundR
				findR = true
			}
			if findR {
				break
			}
		}
		if findR {
			return curRoundReward, findR
		} else {
			return
		}
	}
	// ----------------------------------------------------
	CanCompleteThisRound := func(from string, u *m.User, process *m.SingleActivityProgress, userProgressData *m.UserActivityProgress, list *[]data.SlotActivityReward) (uProp *m.UpdateProp, reward *sp.ActivityReward, can bool) {
		curRoundReward, find := FindRoundReward(process.CurRound, list)
		if find {
			if progress.CurRoundItemCount >= int64(curRoundReward.NeedCount) {
				// 已经完成
				// 修改进度数据
				var curRound int64 = progress.CurRound
				progress.CurRound = (curRound + 1)                                                          // 更新当前轮数
				progress.CurRoundItemCount = (progress.CurRoundItemCount - int64(curRoundReward.NeedCount)) // 更新当前道具数量
				progress.GainRoundReward = curRound                                                         // 更新已获得奖励轮数
				// 准备奖励数据
				giveGoods := make([]m.BaseKV, 0)
				giveGoods = append(giveGoods, m.BaseKV{Key: int64(curRoundReward.GoodTid), Val: int64(curRoundReward.GoodNum)})
				uProp, resGoodsList, boxResList, err := GiveGoodsByKvList(from, u, giveGoods, PSend)
				if err == nil {
					reward = &sp.ActivityReward{
						Round:   curRound,
						Rewards: FormatGoodsInfoSps(resGoodsList),
						BoxRes:  FormatBoxResSps(boxResList),
					}
					userProgressData.ActivityProgressUpsetAndUpdate(progress)
					return uProp, reward, true
				} else {
					userProgressData.ActivityProgressUpsetAndUpdate(progress)
					return nil, nil, false
				}
			} else {
				// 尚未完成，直接计数，不获得奖励
				userProgressData.ActivityProgressUpsetAndUpdate(progress)
				return nil, nil, false
			}
		} else {
			userProgressData.ActivityProgressUpsetAndUpdate(progress)
			return nil, nil, false
		}
	}
	// ----------------------------------------------------
	uProp = m.NewUpdateProp()
	for { //while -- 直到找不到可以完成的任务为止
		uPropRound, reward, canComplete := CanCompleteThisRound(from, u, progress, userProgressData, &slotRoundRewardList)
		if canComplete {
			uProp.Merge(uPropRound)
			ActRewardList = append(ActRewardList, reward)
		} else {
			break
		}
	}

	uProp.MergeKvs_Except(
		data.GlobalEnum.NowTime,
		data.GlobalEnum.EnergyTime,
		data.GlobalEnum.NextRecoverTime,
		data.GlobalEnum.Gold,
		data.GlobalEnum.Diamond,
		data.GlobalEnum.Energy,
		data.GlobalEnum.Shield,
	) //_Except(220001) //除了金币
	return uProp, progress, ActRewardList, nil
}

func actProgressLevelUp_Login(from string, u *m.User, actId int64, addItemNum int64, userProgressData *m.UserActivityProgress, PSend func(interface{}) error) (uProp *m.UpdateProp, progress *m.SingleActivityProgress, ActRewardList []*sp.ActivityReward, err error) {
	actConfige, finderr := GetLoginActConfigeTableInfo(actId)
	if finderr != nil {
		// 该活动不是登录活动
		err = finderr
		return nil, nil, nil, err
	}
	progress, err = GetOrCreateActProgress(u, actId)
	if err != nil {
		// 证明该活动已经过期
		err = errors.NewErrcode(data.Errcode.ServerErr, "不能升级一个已过期的登录活动的进度")
		log.WithFields(log.Fields{
			"err":    err.Error(),
			"actId":  actId,
			"uid":    u.Uid.Hex(),
			"method": "actProgressLevelUp_Login",
		}).Debug("不能升级一个已过期的登录活动的进度")
		return nil, nil, nil, err
	}
	if progress.CurRound == progress.GainRoundReward {
		err = errors.NewErrcode(data.Errcode.ServerErr, "已获取当天登录奖励,不能重复获取")
		log.WithFields(log.Fields{
			"err":             err.Error(),
			"actId":           actId,
			"uid":             u.Uid.Hex(),
			"CurRound":        progress.CurRound,
			"GainRoundReward": progress.GainRoundReward,
			"TotalItemCount":  progress.TotalItemCount,
			"method":          "actProgressLevelUp_Login",
		}).Debug("已获取当天登录奖励,不能重复获取")
		return nil, nil, nil, err
	}
	// ----------------------------------------------------
	FindRoundReward := func(roundId int64, list *[]data.ActivityReward) (curRoundReward data.ActivityReward, findR bool) {
		findR = false
		for _, roundR := range *list {
			if roundId == int64(roundR.Round) {
				curRoundReward = roundR
				findR = true
			}
			if findR {
				break
			}
		}
		if findR {
			return curRoundReward, findR
		} else {
			return
		}
	}
	//----------------
	// var maxRound int64 = 0
	slotRoundRewardList := actConfige.Rewards
	// factorList := actConfige.Factor
	maxRound := int64(len(slotRoundRewardList))

	realSignInRound := progress.TotalItemCount + 1
	// 实际轮数 大于 最大轮数，实际轮数改为1
	if realSignInRound > maxRound {
		realSignInRound = 1
	}
	curRoundReward, find := FindRoundReward(realSignInRound, &slotRoundRewardList)
	if find {
		uProp = m.NewUpdateProp()
		// 准备奖励数据
		giveGoods := make([]m.BaseKV, 0)
		giveGoods = append(giveGoods, m.BaseKV{Key: int64(curRoundReward.GoodTid), Val: int64(curRoundReward.GoodNum)})
		uProp, resGoodsList, boxResList, err := GiveGoodsByKvList(from, u, giveGoods, PSend)
		if err == nil {
			reward := &sp.ActivityReward{
				Round:   realSignInRound, //curRound,
				Rewards: FormatGoodsInfoSps(resGoodsList),
				BoxRes:  FormatBoxResSps(boxResList),
			}
			progress.TotalItemCount = realSignInRound // 实际轮数
			progress.GainRoundReward = progress.CurRound
			u.ChangeLastSignInTime(utils.TNow().Unix())
			userProgressData.ActivityProgressUpsetAndUpdate(progress)
			ActRewardList = append(ActRewardList, reward)
			uProp.MergeKvs_Except(
				data.GlobalEnum.NowTime,
				data.GlobalEnum.EnergyTime,
				data.GlobalEnum.NextRecoverTime,
				data.GlobalEnum.Gold,
				data.GlobalEnum.Diamond,
				data.GlobalEnum.Energy,
				data.GlobalEnum.Shield,
			)
			// if progress.GainRoundReward >= progress.CurRound {
			// 	progress.Close = 1
			// }
			return uProp, progress, ActRewardList, nil
		} else {
			userProgressData.ActivityProgressUpsetAndUpdate(progress)
			err = errors.NewErrcode(data.Errcode.ServerErr, "GiveGoodsByKv失败")
			log.WithFields(log.Fields{
				"err":             err.Error(),
				"actId":           actId,
				"uid":             u.Uid.Hex(),
				"CurRound":        progress.CurRound,
				"GainRoundReward": progress.GainRoundReward,
				"TotalItemCount":  progress.TotalItemCount,
				"realSignInRound": realSignInRound,
				"method":          "actProgressLevelUp_Login",
			}).Debug("GiveGoodsByKv失败")
			return nil, nil, nil, err
		}
	} else {
		userProgressData.ActivityProgressUpsetAndUpdate(progress)
		err = errors.NewErrcode(data.Errcode.ServerErr, "找不到适合轮数的奖励")
		log.WithFields(log.Fields{
			"err":             err.Error(),
			"actId":           actId,
			"uid":             u.Uid.Hex(),
			"CurRound":        progress.CurRound,
			"GainRoundReward": progress.GainRoundReward,
			"TotalItemCount":  progress.TotalItemCount,
			"realSignInRound": realSignInRound,
			"method":          "actProgressLevelUp_Login",
		}).Debug("找不到适合轮数的奖励")
		return nil, nil, nil, err
	}
}

func actProgressLevelUp_Custom(from string, u *m.User, actId int64, addItemNum int64, userProgressData *m.UserActivityProgress, PSend func(interface{}) error) (uProp *m.UpdateProp, progress *m.SingleActivityProgress, ActRewardList []*sp.ActivityReward, err error) {
	actConfige, finderr := GetOtherActConfigeTableInfo(actId)
	if finderr != nil {
		// 该活动不是其他活动
		err = finderr
		return nil, nil, nil, err
	}
	progress, err = GetOrCreateActProgress(u, actId)
	if err != nil {
		// 证明该活动已经过期
		err = errors.NewErrcode(data.Errcode.ServerErr, "不能升级一个已过期的活动的进度")
		log.WithFields(log.Fields{
			"err":    err.Error(),
			"actId":  actId,
			"uid":    u.Uid.Hex(),
			"method": "actProgressLevelUp_Login",
		}).Debug("不能升级一个已过期的活动的进度")
		return nil, nil, nil, err
	}
	var maxRound int64 = 0
	RoundRewardList := actConfige.Rewards
	factorList := actConfige.Factor
	if RoundRewardList != nil {
		maxRound = int64(len(RoundRewardList))
	}
	progress.CurRoundItemCount = (progress.CurRoundItemCount + addItemNum)
	progress.TotalItemCount = (progress.TotalItemCount + addItemNum)
	if progress.GainRoundReward >= int64(maxRound) || progress.CurRound > maxRound {
		// 已经获得最高阶段奖励：直接计数，不获得奖励
		// 当前轮数超过最高阶段奖励 ：直接计数，不获得奖励
		userProgressData.ActivityProgressUpsetAndUpdate(progress)
		return nil, progress, nil, nil
	}
	// ----------------------------------------------------
	FindRoundReward := func(roundId int64, list *[]data.ActivityReward) (curRoundReward data.ActivityReward, findR bool) {
		findR = false
		for _, roundR := range *list {
			if progress.CurRound == int64(roundR.Round) {
				curRoundReward = roundR
				findR = true
			}
			if findR {
				break
			}
		}
		if findR {
			return curRoundReward, findR
		} else {
			return
		}
	}
	// ----------------------------------------------------
	CanCompleteThisRound := func(from string, u *m.User, process *m.SingleActivityProgress, userProgressData *m.UserActivityProgress, list *[]data.ActivityReward, factorL *[]data.WeightKV, PSend func(interface{}) error) (uProp *m.UpdateProp, reward *sp.ActivityReward, can bool) {
		curRoundReward, find := FindRoundReward(process.CurRound, list)
		var needCount int64 = 1 //根据typeEnum 向Factor([]data.WeightKV)中找数据
		if find {
			if progress.CurRoundItemCount >= needCount {
				// 已经完成
				// 修改进度数据
				var curRound int64 = progress.CurRound
				progress.CurRound = (curRound + 1)                                    // 更新当前轮数
				progress.CurRoundItemCount = (progress.CurRoundItemCount - needCount) // 更新当前道具数量
				progress.GainRoundReward = curRound                                   // 更新已获得奖励轮数
				// 准备奖励数据
				giveGoods := make([]m.BaseKV, 0)
				giveGoods = append(giveGoods, m.BaseKV{Key: int64(curRoundReward.GoodTid), Val: int64(curRoundReward.GoodNum)})
				uProp, resGoodsList, boxResList, err := GiveGoodsByKvList(from, u, giveGoods, PSend)
				if err == nil {
					reward = &sp.ActivityReward{
						Round:   curRound,
						Rewards: FormatGoodsInfoSps(resGoodsList),
						BoxRes:  FormatBoxResSps(boxResList),
					}
					userProgressData.ActivityProgressUpsetAndUpdate(progress)
					return uProp, reward, true
				} else {
					userProgressData.ActivityProgressUpsetAndUpdate(progress)
					return nil, nil, false
				}
			} else {
				// 尚未完成，直接计数，不获得奖励
				userProgressData.ActivityProgressUpsetAndUpdate(progress)
				return nil, nil, false
			}
		} else {
			userProgressData.ActivityProgressUpsetAndUpdate(progress)
			return nil, nil, false
		}
	}
	// ----------------------------------------------------
	uProp = m.NewUpdateProp()
	for { //while -- 直到找不到可以完成的任务为止
		uPropRound, reward, canComplete := CanCompleteThisRound(from, u, progress, userProgressData, &RoundRewardList, &factorList, PSend)
		if canComplete {
			uProp.Merge(uPropRound)
			ActRewardList = append(ActRewardList, reward)
		} else {
			break
		}
	}
	uProp.MergeKvs_Except(
		data.GlobalEnum.NowTime,
		data.GlobalEnum.EnergyTime,
		data.GlobalEnum.NextRecoverTime,
		data.GlobalEnum.Gold,
		data.GlobalEnum.Diamond,
		data.GlobalEnum.Energy,
		data.GlobalEnum.Shield,
	)
	return uProp, progress, ActRewardList, nil
}

func actProgressLevelUp_BossCombat(u *m.User, actId int64, addItemNum int64, userProgressData *m.UserActivityProgress) (uProp *m.UpdateProp, progress *m.SingleActivityProgress, ActRewardList []*sp.ActivityReward, err error) {
	actConfige, finderr := GetWorldBossActConfigeTableInfo(actId)
	if finderr != nil {
		// 该活动不是世界BOSS活动
		err = finderr
		return nil, nil, nil, err
	}
	fmt.Println(actConfige.ActivID)
	progress, err = GetOrCreateActProgress(u, actId)
	if err != nil {
		// 证明该活动已经过期
		err = errors.NewErrcode(data.Errcode.ServerErr, "不能升级一个已过期的活动的进度")
		log.WithFields(log.Fields{
			"err":    err.Error(),
			"actId":  actId,
			"uid":    u.Uid.Hex(),
			"method": "actProgressLevelUp_Login",
		}).Debug("不能升级一个已过期的活动的进度")
		return nil, nil, nil, err
	}
	err = errors.NewErrcode(data.Errcode.ServerErr, "不能以这种方式修改世界BOSS进度")
	return nil, nil, nil, err
}
